{% extends '../base.html' %}
{% block css %}
{% load static %}
<link ref="stylesheet" type="text/css" href="{% static 'study/css/examing.css' %}">
<style>
  .vir-ins>div>div {
    height: 120px;
  }

  .vir-ins {
    position: relative;
    margin-top: 20px;
  }

  .vir-ins>.ins-stat {
    position: absolute;
    top: 0;
    right: 0;
    background-color: #eeeeee;
    padding: 5px 15px;
    display: inline-block;
  }

  .con-list-item {
    width: 95% !important;
  }

  .con-list-item .item-con {
    width: 500px;
  }

  #left-list {
    /* color: red; */
    width: 650px;
    height: calc(100vh - 170px);
    overflow-y: auto;
    padding: 0 20px;
  }

  .unfold {
    width: 0px !important;
    overflow: hidden !important;
    padding: 0 !important;
  }

  .unfold-right {
    width: calc(100vw - 40px) !important;
    margin-left: 20px;
  }

  #right-content {
    position: relative;
    z-index: 999;
    /*flex: 1 0 auto;*/
    width: calc(100vw - 750px);
    height: calc(100vh - 170px);
    background-color: #070707;
    margin-right: 20px;
    background-image: url('ttpstatic/images/loading3.gif');
    background-repeat: no-repeat;
    background-position: center;
    background-size: 30% 30%;
    overflow-x: auto;
    transition: width 0.5s;
    -webkit-transition: width 0.5s;
  }
  #right-content > img {
    display: block;
    margin: 7% auto;
  }
  #buy-bar-in{
    width: 670px;
    position: fixed;
    bottom: 0;
  }
  
  #buy-bar-in > div{
    /* width: 1440px; */
    height: 80px;
    background-color: #ffffff;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
  }
  
  #buy-bar-in > div  span{
    margin-left: 30px;
    display: block;
    background-color: #ff9900;
    padding: 20px 50px;
    border-radius: 5px;
    color: #eeeeee;
    cursor: pointer;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
  }
  #vnc_container img {
    margin: auto;
  }
  .image-container {
    position: relative;
    width: 285px; /* 调整容器宽度 */
    height: 174px; /* 调整容器高度 */
  }
  
  /* 图片元素 */
  .image-container img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover; /* 根据容器尺寸裁剪/缩放图片 */
  }
  
  /* 无法显示图片时的背景块 */
  .image-container .fallback-text {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #5e889e; /* 设置背景颜色 */
      display: flex;
      justify-content: center; /* 文字水平居中 */
      align-items: center; /* 文字垂直居中 */
      color: #fff; /* 文字颜色 */
      font-size: 18px; /* 文字大小 */
  }
  .html-bar {
    background-color: #eee;
    border-radius: 15px !important;
    box-shadow: 3px 5px 10px #e2e2e2;
    /*color: #fff !important;*/
  }
</style>
{% endblock css %}

{% block content %}
<div id="experiment-head" style="width: 100vw;">
  <span>实验>实验详情</span>
  <div style="float: right; margin-right: 20px; cursor: pointer;" onclick="onFold()">
    <i class="layui-icon layui-icon-screen-restore" style="font-size: 20px; color: #666;"></i> 
    <span style="font-size: 16px; line-height: 22px;">折叠/展开</span>
  </div>
</div>
{% if error_msg %}
<div class="error_msg">
  <span>{{error_msg}}</span>
</div>
{% endif %}
<div id="main-con-ex" class="flex-row-between" style="align-items: flex-start;">
  <div id="left-list">
    <!-- <span>test</span> -->
    <div id="experiment-info" class="flex-row-between align-items-start">
      <div class="avatar-name" id="image-container">
        <div class="image-container">
          <img src="https://os-image-bj-1258514725.cos.ap-beijing.myqcloud.com/media/WechatIMG919.jpeg" width=285 height=174 />
          <div class="fallback-text">{{experiment.experiment_name}}</div>
        </div>
        <div class="flex-column-start experiment-name">
          <p class="title24">{{experiment.experiment_name}}</p>
          <!-- {% autoescape off %}
            <p class="title18">{{experiment.intro|truncatewords:25}}</p>
            {% endautoescape %} -->
          <div class="title18">
            {% if experiment.course_names %}
            <span>{{experiment.course_names|truncatewords:10}} | </span>
            {%endif%}
            <span>{{experiment.teacher_names|truncatewords:10}}</span>
          </div>
        </div>
      </div>
      <div class="user-count flex-column-between">
        {% include '../components/experiment_user_count.html' with user_count=experiment.user_count %}
        <div class="title18">
          时长：{{experiment.duration}}分钟
        </div>
      </div>
    </div>

    <!-- 登录实验实例 -->
    {% if error_code == 0 %}
    {% if experiment.instance|length > 0 %}
    <div class="experiment-con-head flex-row-start">
      <span class="head-tip"></span>
      <span id="login-vm" class="title24"><a href="#login-vm">登录实验实例</a></span>
      {% if user.phone == "15198734046" %}
      <span onclick=goTest() class="title24">test</span>
      {%endif%}
    </div>
    {% comment %} <div class="title18">
      <p>实验ID：{{experiment.id}}&nbsp;&nbsp; vnc码：{{vnccode}} &nbsp;&nbsp; 登录密码：Adr5@_d6dhnr </p>
      <p style="margin-top: 20px;">VNC管理终端地址的有效期为15秒，若地址失效，请刷新重试</p>
    </div> {% endcomment %}
    {% endif %}
    <div id="vms">
      {% for ins in experiment.instance %}
      <div class="vir-ins title18">
        <input type="hidden" class="insStatus" value="{{ins.Status}}" />
        <p style="display: none; margin-bottom: 10px; font-size: 14px;">10秒钟后刷新实例状态</p>
        {% comment %} <p>名称：{{ins.Name}}</p> {% endcomment %}
        <div class="flex-row-start" style="flex-wrap: wrap">
          {% comment %} <div class="flex-column-around vir-ins-items align-items-start" style="width: 300px;">
            <p>镜像：{{ins.ImageName}}</p>
            <p>架构：{{ins.Arc}}</p>
          </div>
          <div class="flex-column-around vir-ins-items align-items-start" style="width: 600px;">
            <p>IP：{{ins.PrivateIpAddresses}}/{{ins.PublicIpAddresses}}</p>
            <p>架构：{{ins.OsName}}</p>
          </div> {% endcomment %}
          <div class="flex-row-around vir-ins-opes" style="height: 80px; gap: 15px;">
            {% if ins.Status == 'UNCREATED' %}
            <span onclick="onCreate('{{ins.ImageId}}', this)" class="btn-short vir-create">创建</span>
            {% elif ins.Status == 'STOPPED' %}
            <span onclick="onInsAction('{{ins.InsId}}', 'start')" class="btn-short vir-open">开机</span>
            <span onclick="onInsAction('{{ins.InsId}}', 'recovery', this)" style="background-color: rgb(203, 145, 146);"
              class="btn-short vir-restore">回收</span>
            {% elif ins.Status == 'RUNNING' %}
            {% comment %} <span onclick="goVNC('{{ins.vnc_url}}', '{{experiment.id}}', '{{vnccode}}')"
              class="btn-short btn vir-login">链接vnc</span> {% endcomment %}
            <span onclick="onInsAction('{{ins.InsId}}', 'shutdown', this)" style="background-color: rgb(255, 199, 94);"
              class="btn-short vir-shutdown">关机</span>
            <span onclick="onInsAction('{{ins.InsId}}', 'recovery', this)" style="background-color: rgb(203, 145, 146);"
              class="btn-short vir-restore">回收</span>
            {%else%}
            <span onclick="onInsAction('{{ins.InsId}}', 'recovery', this)" style="background-color: rgb(203, 145, 146);"
              class="btn-short vir-restore">回收</span>
            {% endif %}
          </div>
        </div>
        <span class="ins-stat">
          {{ins.StatusLabel}}
        </span>
      </div>
      {% endfor %}
    </div>
    {% else %}
    <!-- 若有错误码 error_code > 0 -->
    {% if error_code == 2 and experiment.type == 1 %}
    <!-- 如果是课程实验，推荐课程 -->
    <div class="experiment-con-head flex-row-start">
      <span class="head-tip"></span>
      <span class="title24">请购买相关课程后进行实验</span>
    </div>
    {% for course in connect_course %}
    {% include '../components/course_list_item.html' %}
    {% endfor %}
    {% else %}
    <div class="experiment-con-head flex-row-start">
      <span class="head-tip"></span>
      <span class="title24">登录实验实例</span>
    </div>
    <div class="error-div flex-column-center" style="width: 650px;">
      {{error}}
    </div>
    {% endif %}
    {% endif %}

    <!-- 实验介绍内容 -->
    <div class="experiment-con-head flex-row-start">
      <span class="head-tip"></span>
      <span class="title24">实验介绍</span>
    </div>
    <div class="show-html" id="experiment-intro">
      {% autoescape off %}
      {{experiment.intro| safe}}
      {% endautoescape %}
    </div>
    {% if describe_list|length > 0 %}
    {% for index, item in describe_list %}
    <div class="experiment-con-head flex-row-start">
      <span class="head-tip"></span>
      <span class="title24">实验指导书</span>
      <span class="title24" style="line-height: 35px; margin-left: 5px;">{{ index|add:1 }}</span>
    </div>
    <div class="show-html html-bar" id="experiment-desc">
      {% autoescape off %}
      {{item.detail| safe}}
      {% endautoescape %}
    </div>
    {% endfor %}
    {% endif %}
  </div>
  {% for ins in experiment.instance %}
    {% if ins.Status == 'UNCREATED' %}
    <div id="right-content">
      <img src='../../ttpstatic/images/novnc.png' />
    </div>
    {% elif ins.Status == 'STOPPED' %}
    <div id="right-content">
      <img src='../../ttpstatic/images/novnc-start.png' />
    </div>
    {% else %}
    <div id="right-content">
      <iframe id="vnc_container" src="" width="100%" height="100%"></iframe>
    </div>
    {% endif %}
  {% endfor %}

  {% comment %} <div>
    {% include '../components/more_course.html' %}
    {% include '../components/more_experiment.html' %}
    {% include '../components/more_exam.html' %}
  </div> {% endcomment %}
</div>
{% if error_code == 2 %}
{% comment %} <div id="buy-bar-in">
  <div>
    <span onclick=goUrl("{% url 'study:buyExperiment' pk=experiment.id %}")> 购买实验 </span>
  </div>
</div> {% endcomment %}
{%endif%}
{% if error_code == 0 and experiment.id %}
{% comment %} <div id="buy-bar-in">
  <div>
    <span onclick=goUrl("{% url 'study:report' pk=experiment.id %}")> 提交报告 </span>
  </div>
</div> {% endcomment %}
{%endif%}
<div id="loading-bar" class="layui-progress" lay-filter="demo" lay-showPercent="true">
  <div class="layui-progress-bar" lay-percent="0%"></div>
</div>
{% if user.phone == "15198734046" %}
<div style="position: fixed; width: 300px; height: 200px; overflow-x: scroll; top: 50px; right: 20px;" id="logger">
</div>
{%endif%}

{% endblock content %}

{% block script %}
<script src="/static/study/layui/layui.js" charset="utf-8"></script>
<script src="/static/js/tools.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.6.0/base64.min.js"></script>
<script>
  /*
  'UNCREATED': '未创建',
  'PENDING': '操作中..',
  'LAUNCH_FAILED': '创建失败',
  'RUNNING': '运行中..',
  'STOPPED': '关机',
  'STARTING': '开机中..',
  'STOPPING': '关机中..',
  'REBOOTING': '重启中..',
  'SHUTDOWN': '停止待销毁',
  'TERMINATING': '销毁中..'
  */
  var loading = false
  var layer
  var element
  var novnc_url = ""
  var link_count = 0
  var unfold = false
  var btnHanleing = false
  layui.use('layer', function () {
    layer = layui.layer;
  });
  layui.use('element', function () {
    element = layui.element;
  });

  function onFold() {
    if(!unfold) {
      document.getElementById("left-list").classList.add("unfold");
      document.getElementById("right-content").classList.add("unfold-right");
    }else {
      document.getElementById("left-list").classList.remove("unfold");
      document.getElementById("right-content").classList.remove("unfold-right");
    }
    unfold = !unfold;
  }

  function startLoading(index) {
    loading = true
    layer.close(index)
    element.progress('demo', '50%')
  }

  function endLoading() {
    element.progress('demo', '100%')
    loading = false
    window.setTimeout(function () {
      element.progress('demo', '0%')
    }, 3000)
  }

  function reload() {
    location.href = location.href + "#login-vm"
  }

  function onCreate(ImageId, node) {
    console.log(ImageId, event)
    if (loading) return;
    if (btnHanleing) return;
    layer.confirm('确定创建虚拟机实例？', { title: '提示' }, function (index) {
      startLoading(index)
      models.insModel.action({
        action: 'create',
        imageId: ImageId,
        envId: {{ experiment.environment.id }}
      }, function(res) {
        console.log('~create res', res)
        endLoading()
        let opsEls = document.getElementsByClassName('btn-short')
        for(let el of opsEls) {
          el.style.cursor = "not-allowed"
          el.style.backgroundColor = "#e6e6e6"
        }
        btnHanleing = true
        setTimeout(() => location.reload(), 5000)
        layer.msg(err.message, {
          icon: 1,
          time: 5000 //2秒关闭（如果不配置，默认是3秒）
        }, function () {
          // location.href = location.href + "#login-vm"
        });
      }, function(err) {
        endLoading()
        layer.msg(err.message, {
          icon: 1,
          time: 5000 //2秒关闭（如果不配置，默认是3秒）
        }, function () {
        });
      })
    }, function(cancel) {
      loading = false
      console.log('cancel', cancel)
    })
  }

  function onInsAction(InsId, action, node) {
    console.log(InsId, event)
    //not-allowed
    if (loading) return;
    if (btnHanleing) return;
    layer.confirm(`确定${action}虚拟机实例？`, { title: '提示' }, function (index) {
      startLoading(index)
      models.insModel.action({
        action: action,
        insId: InsId,
        envId: {{ experiment.environment.id }}
      }, function(res) {
    endLoading()
    let opsEls = document.getElementsByClassName('btn-short')
    for(let el of opsEls) {
      el.style.cursor = "not-allowed"
      el.style.backgroundColor = "#e6e6e6"
    }
    btnHanleing = true
    // todo 延时3秒完成
    layer.msg(action + '成功，3秒后刷新页面', {
      icon: 1,
      time: 5000 //2秒关闭（如果不配置，默认是3秒）
    }, function () {
      setTimeout(() => location.reload(), 5000)
      // location.href = location.href + "#login-vm"
    });
  }, function(err) {
    endLoading()
    layer.msg(err.message, {
      icon: 1,
      time: 5000 //2秒关闭（如果不配置，默认是3秒）
    }, function () {
    });
  })
    }, function(cancel) {
    loading = false
    console.log('cancel', cancel)
  })
  }

  function logger(msg) {
    var n = document.getElementById("logger");
    if (n) {
      var p = n.innerHTML;
      n.innerHTML = p + "<p>" + msg + "</p>"
      console.log(msg)
    }
  }

  function goTest() {
    logger("goTest")
    try {
      if (window.app || typeof app != "undefined") {
        logger("go app.test")
        try {
          app.test()
        } catch (e) {
          logger(e.toString())
        }
      } else {
        logger("no windows.app")
      }
    } catch (e) {
      logger(e.toString())
    }
  }

  function goVNC(vnc_url, id, pwd) {
    console.log('~vnc_url', novnc_url)
    logger("goVNC")
    try {
      if (window.app || typeof app != "undefined") {
        logger("go app.login")
        try {
          app.login(id, pwd)
        } catch (e) {
          logger(e.toString())
        }
      } else {
        //logger("go windows.open")
        //console.log('~vnc_url', 'http://192.168.0.104:8100' + '/vnc/?env=' + {{ experiment.environment.id }} + '&experiment=' + {{ experiment.id }} + '&vnc_url=' + Base64.encode(vnc_url))
        //window.open('/vnc/?env=' + {{ experiment.environment.id }} + '&experiment=' + {{ experiment.id }} + '&vnc_url=' + Base64.encode(vnc_url), '_blank');
        let vnc_display = document.getElementById('vnc_container');
        //vnc_display.src = 'http://127.0.0.1:8100' + '/vnc/?env=' + {{ experiment.environment.id }} + '&experiment=' + {{ experiment.id }} + '&vnc_url=' + Base64.encode(vnc_url);
        vnc_display.src = novnc_url;
        /*if (vnc_display.attachEvent) {
          // IE
          vnc_display.attachEvent('onload', function() {
            console.log('iframe加载完毕！')
            setVNC()
          })
        } else { // 非IE
          vnc_display.onload = function() {
              console.log('iframe加载完毕！')
              setVNC()
            }
        }*/
      }
    }catch (e) {
      logger(e.toString())
    }
    return
  }
  function autoGoVnc() {
    logger("goVNC")
    try {
      if (window.app || typeof app != "undefined") {
        logger("go app.login")
        try {
          app.login(id, pwd)
        } catch (e) {
          logger(e.toString())
        }
      } else {
        let vnc_display = document.getElementById('vnc_container');
        vnc_display.src = novnc_url;
        /*if (vnc_display.attachEvent) {
          // IE
          vnc_display.attachEvent('onload', function() {
            console.log('iframe加载完毕！')
            setVNC()
          })
        } else { // 非IE
          vnc_display.onload = function() {
              console.log('iframe加载完毕！')
              setVNC()
            }
        }*/
      }
    }catch (e) {
      logger(e.toString())
    }
    return
  }

  function setVNC() {
    let iframeEl = document.getElementById('vnc_container').contentWindow.document;
    //let innerIframe = iframeEl.getElementById('ssh-iframe');
    console.log('~vnc_canvas', iframeEl.getElementTagName('canvas'))
  }

  var vmNodeStr = `<div class="vir-ins title18">
            <input type="hidden" class="insStatus" value="[[ins.Status]]" />
            <p style="display: none; margin-bottom: 10px; font-size: 14px;">10秒钟后刷新实例状态</p>
            <div class="flex-row-start" style="flex-wrap: wrap">
              <div class="flex-row-around vir-ins-opes" style="height: 80px; gap: 15px;">
                [[statusStr]]
              </div>
            </div>
            <span class="ins-stat">
              [[ins.StatusLabel]]
            </span>
          </div>`;
  var createStr = `<span onclick="onCreate('[[imageId]]', this)" class="btn-short vir-create">创建</span>`
  var stoppedStr = `<span onclick="onInsAction('[[insId]]', 'start')" class="btn-short vir-open">开机</span>
                  <span onclick="onInsAction('[[insId]]', 'recovery', this)" style="background-color: rgb(203, 145, 146);" class="btn-short vir-restore">回收</span>`
  var runningStr = `<span onclick="onInsAction('[[insId]]', 'shutdown', this)" style="background-color: rgb(255, 199, 94);" class="btn-short vir-shutdown">关机</span>
                  <span onclick="onInsAction('[[insId]]', 'recovery', this)" style="background-color: rgb(203, 145, 146);" class="btn-short vir-restore">回收</span>`
  var elseStr = `<span onclick="onInsAction('[[insId]]', 'recovery', this)"  style="background-color: rgb(203, 145, 146);" class="btn-short vir-restore">回收</span>`

  window.onload = function () {

    //console.log('~error_code', {{error_code}})
    if({{error_code}} == 2) {
      window.location.href = "/experiment/buy/" + {{experiment.id}} + "/"
    }

    setTimeout(function () {
      if (window.navigator.userAgent.indexOf("JavaFX") >= 0) {
        logger(window.navigator.userAgent.indexOf("JavaFX"))
        logger(app.login.toString())
        // location.href = location.href 
      }
    }, 1000)

    function loadStatus () {
      var vmsStr = ""
      var id = {{ experiment.id }}
    
      var vnccode = "{{vnccode}}"
      models.experimentModel.item({{ experiment.id }}, function (res) {
        if (res.error_code == 0) {
          //console.log('~status', res.data.instance[0].Status)
          if(res.data.vnc_url && link_count == 0) {
            //console.log('~res.data.vnc_url', res.data.vnc_url)
            let icd = res.data.instance[0].doraemon.slice(res.data.instance[0].doraemon.indexOf('A'), res.data.instance[0].doraemon.indexOf('nr') + 2)
            novnc_url = res.data.vnc_url + '?asd=&' + encodeURIComponent('abc=123@;hash&kk=替代方式$%^&pcode=' + res.data.instance[0].doraemon)
            autoGoVnc();
            link_count++;
          }
          let inTimer = null; 
          if(res.data.instance[0].Status == 'PENDING') {
            inTimer = setInterval(function () {
              loadStatus()
            }, 15000) 
            return;
          }else {
            clearInterval(inTimer)
          }
          if(!res.data.vnc_url){
            return setTimeout(function () {
              loadStatus()
            }, 5000) 
          }
          /*
          if(res.data.instance.length && link_count == 0) {
            if(res.data.instance[0].Status == 'UNCREATED') {
              novnc_url = '../../static/images/novnc.png'
          if (res.error_code == 0) {
            if(res.data.vnc_url && link_count == 0) {
              console.log('~res.data.vnc_url', res.data.vnc_url)
              novnc_url = res.data.vnc_url
              autoGoVnc();
              link_count++;
            }
            /*
            if(res.data.instance.length && link_count == 0) {
              if(res.data.instance[0].Status == 'UNCREATED') {
                novnc_url = '../../static/images/novnc.png'
                autoGoVnc();
                link_count++;
              }
            }
            */
          res.data.instance.map((v, i) => {
            vmsStr += vmNodeStr.replaceAll("[[ins.Status]]", v.Status)
              .replaceAll("[[ins.Name]]", v.Name)
              .replaceAll("[[ins.ImageName]]", v.ImageName)
              .replaceAll("[[ins.Arc]]", v.Arc)
              .replaceAll("[[ins.PrivateIpAddresses]]", v.PrivateIpAddresses)
              .replaceAll("[[ins.PublicIpAddresses]]", v.PublicIpAddresses)
              .replaceAll("[[ins.OsName]]", v.OsName)
              .replaceAll("[[ins.StatusLabel]]", v.StatusLabel)
            switch (v.Status) {
              case 'UNCREATED':
                vmsStr = vmsStr.replaceAll("[[statusStr]]", createStr.replaceAll("[[imageId]]", v.ImageId))
                break;
              case 'STOPPED':
                vmsStr = vmsStr.replaceAll("[[statusStr]]", stoppedStr.replaceAll("[[insId]]", v.InsId))
                break;
              case 'RUNNING':
                vmsStr = vmsStr.replaceAll("[[statusStr]]", runningStr.replaceAll("[[insId]]", v.InsId).replaceAll("[[id]]", id).replaceAll("[[pwd]]", vnccode).replaceAll("[[vnc_url]]", v.vnc_url))
                break;
              default:
                vmsStr = vmsStr.replaceAll("[[statusStr]]", elseStr.replaceAll("[[insId]]", v.InsId))
            }
          })
          document.getElementById("vms").innerHTML = vmsStr
        }else {
          console.log('no res')
        }
        return setTimeout(function () {
          loadStatus()
        }, 5000) 
      }, function (err) {
        console.log('~loadStatus err', err)
        //location.reload()
      })
    }
    loadStatus()
  }

</script>
{% endblock script %}